package chapter05

/**
  * create by undeRdoG on  2021-05-30  13:37
  * 凡心所向，素履以往，生如逆旅，一苇以航。
  */
object Test05_Lambda {

  def main(args: Array[String]): Unit = {
    /**
    *   把 匿名函数直接赋值给一个 变量，通过 该变量即可调用该匿名函数
    * */
    val fun = (name: String) => {println(name)}
    fun("Peter")


    // 定义一个函数，以函数作为参数 入参函数的 参数类型为String  返回值为 Unit

    /*
    *  对于一般的函数，是将具体的参数传递到函数中进行操作
    *  而 Scala 允许 将一个函数操作作为参数传递进来，这样 Lambda表达式就很有意义了
    * */
    def f(func: String => Unit)={
      func("Alice")
    }
    f(fun)
    f((name: String) => {println(name.length)})


    //  匿名函数的简化原则
    //(1) 参数的类型可以省略，会根据形参的类型省略
    //(2)  如果只有一个参数，那么括号可以省略
    f(name =>{
      println(name)
    })

    // (3) 如果匿名函数的函数体，{} 可以省略
    f(name => println(name))

    //(4) 如果参数只出现一次，那么参数可以省略，且后面的参数 可以使用 _  来代替
    f(println(_))

    //(5) 如果可以推断出，当前传入的 println 是一个函数体，可以直接省略下划线
    f(println)


    /**
    *   实际事例，定义一个 “二元运算” 函数，只操作 1 和 2 两个数，具体的运算通过参数传入
    * */

    def dualFunctionOneAndTwo(func: (Int,Int) => Int) : Int = {
      func(1,2)
    }

    val add = (a: Int,b: Int) => a + b

    val minus = (a: Int,b: Int) => a - b

    println(dualFunctionOneAndTwo(add))
    println(dualFunctionOneAndTwo(minus))


    println(dualFunctionOneAndTwo( _ + _ ))
  }
}
